﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Media;
using System.Threading;

namespace TextToSpeechEngine
{
    public class TTSEngine
    {

        PhonemeDatabase phonemeDatabase;
        WordRepresentationDatabase wordRepresentationDatabase;
        private Thread ttsThread;

        //play sounds
        private SoundPlayer soundPlayer;

        public TTSEngine()
        {
            phonemeDatabase = new PhonemeDatabase();
            wordRepresentationDatabase = new WordRepresentationDatabase();
            this.ttsThread = new Thread(readISeeYou);
        }

        public void LoadFromFile(string phonemeDatabaseFilePath, string wordRepresentationDatabaseFilePath)
        {            
            phonemeDatabase = new PhonemeDatabase();
            wordRepresentationDatabase = new WordRepresentationDatabase();

            //load phonemes (and their wav files)
            phonemeDatabase.LoadFromFile(phonemeDatabaseFilePath);
            //load the word representation database
            wordRepresentationDatabase.LoadFromFile(wordRepresentationDatabaseFilePath);
        }

        // For threaded reading
        private void readISeeYou()
        {
            readLine("I see you");
        }

        public void SayISeeYou()
        {
            this.ttsThread.Start(); // What if we call this twice? Will the thread restart?
        }

        public void readLine(string lineToBeRead)
        {
            //not stolen from: http://stackoverflow.com/questions/70405/does-c-have-a-string-tokenizer-like-javas            
            // Split string on spaces. This will separate all the words in a string
            string[] words = lineToBeRead.Split(' ');
            foreach (string word in words)
            {
                Debug.Write(word + "\n");
                
                //check if the word is inside the word representation database
                foreach(WordRepresentation wordRepresentation in wordRepresentationDatabase.WordRepresentations)
                {
                    //waha
                    if (word.ToLower().Equals(wordRepresentation.Word.ToLower()))
                    {
                        //match found
                        Debug.Write("Match found for " + word + "!\n");

                        //play sound using phonemes

                        //wav sound list
                        List<WAVSound> phonemeWavs = new List<WAVSound>();
                        //volume list
                        List<double> phonemeVolumes = new List<double>();
                        //end cut list
                        List<double> phonemeEndCuts = new List<double>();

                        //get phonemes
                        foreach(int phonemeID in wordRepresentation.PhonemeIDs)
                        {
                            //pick out the right phoneme
                            foreach(Phoneme phoneme in phonemeDatabase.PhonemeList)
                            {
                                if (phoneme.ID == phonemeID - 1)//index starts at 1 in the word representation database, 0 in the phoneme id enumerization
                                {
                                    Debug.Write(phoneme.SoundDescriptionList[0] + " ");

                                    phonemeWavs.Add(phoneme.SoundList[0]);
                                    phonemeVolumes.Add(1.0);
                                    phonemeEndCuts.Add(phoneme.SoundList[0].GetDuration());

                                    break;
                                }
                            }
                            Debug.Write("\n");
                        }

                        //put together the word wav sound using the phoneme wav sound list
                        WAVSound wordSound = WAVSound.JoinSounds("waha",phonemeWavs[0].SampleRate,phonemeWavs[0].BitsPerSample,phonemeWavs[0].NumberOfChannels,phonemeWavs,phonemeEndCuts,phonemeVolumes);

                        //taken from TextToSpeechSolution
                        soundPlayer = new SoundPlayer();
                        wordSound.GenerateMemoryStream();
                        wordSound.WAVMemoryStream.Position = 0; // Manually rewind stream 
                        soundPlayer.Stream = null;
                        soundPlayer.Stream = wordSound.WAVMemoryStream;
                        soundPlayer.Play();

                        Debug.Write("duration: " + wordSound.GetDuration() + "\n");
                        
                        //pause until the word sound has been played and wait a while before the next word
                        System.Threading.Thread.Sleep((int)(wordSound.GetDuration()*1000) + 100);
                    }
                }
            }
        }
    }
}
